﻿using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Xml;
using Microsoft.Win32;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept.Enums;
using System.Windows.Media;
using SHomeWorkshop.LunarMind;

namespace SHomeWorkshop.LunarConcept.Widgets
{
    /// <summary>
    /// 创建时间：2012年1月4日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：图画框部件。
    /// </summary>
    public class PictureBox : ContentWidget
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [静态构造方法]初始化默认图像。
        /// </summary>
        static PictureBox()
        {
            defaultBitmap = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/Images/LunarConcept_small.png"));

            //读取内置图标
            innerIcon_A = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_A.png"));
            innerIcon_B = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_B.png"));
            innerIcon_C = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_C.png"));
            innerIcon_D = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_D.png"));
            innerIcon_X = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_X.png"));
            innerIcon_Arrow = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_Arrow.png"));
            innerIcon_Question = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_Question.png"));
            innerIcon_Right = new BitmapImage(new Uri("pack://application:,,,/LunarMind;component/ConceptWidgets/InnerIcons/InnerIcons/InnerIcon_Right.png"));

        }

        /// <summary>
        /// [构造方法]
        /// </summary>
        /// <param name="masterEditor">所属的页面编辑器。</param>
        public PictureBox(PageEditorReader masterEditor)
            : base(masterEditor)
        {
            widgetPadding = new Thickness(0);

            widgetType = Enums.WidgetTypes.PictureBox;
            widgetClassLocalName = Widget.GetWidgetClassLocalName(this.GetType().Name);

            this.masterEditor = masterEditor;

            this.mainImage.Cursor = Cursors.Hand;
            this.mainImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            this.mainImage.VerticalAlignment = System.Windows.VerticalAlignment.Center;

            this.baseDockPanel.Children.Add(this.mainImage);
            DockPanel.SetDock(this.mainImage, Dock.Left);//默认右侧显示文本。
            this.MainBorder.Child = this.baseDockPanel;

            RefreshLayerIndex();

            this.baseDockPanel.Margin = this.mainTextPanel.Margin
                = this.mainImage.Margin = defaultPadding;

            //最后添加文本面板。
            this.baseDockPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            this.baseDockPanel.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            this.baseDockPanel.Children.Add(this.mainTextPanel);
            DockPanel.SetDock(this.mainTextPanel, Dock.Right);//默认图像在左、文本在右。
        }

        #endregion


        #region 字段与属性===================================================================================================
        
        private static Thickness defaultPadding = new Thickness(2);

        private DockPanel baseDockPanel = new DockPanel();

        /// <summary>
        /// 默认图像。未设置图像数据时显示此图。
        /// </summary>
        private static BitmapImage defaultBitmap;

        /// <summary>
        /// [静态只读]默认图标。
        /// </summary>
        public static BitmapImage DefaultBitmap
        {
            get { return PictureBox.defaultBitmap; }
        }

        private static BitmapImage innerIcon_A;
        /// <summary>
        /// [静态只读]内置图标A字。
        /// </summary>
        public static BitmapImage InnerIcon_A
        {
            get { return PictureBox.innerIcon_A; }
        }

        private static BitmapImage innerIcon_Arrow;
        /// <summary>
        /// [静态只读]内置图标，蓝色小箭头。
        /// </summary>
        public static BitmapImage InnerIcon_Arrow
        {
            get { return PictureBox.innerIcon_Arrow; }
        }

        private static BitmapImage innerIcon_B;
        /// <summary>
        /// [静态只读]内置图标B字。
        /// </summary>
        public static BitmapImage InnerIcon_B
        {
            get { return PictureBox.innerIcon_B; }
        }

        private static BitmapImage innerIcon_C;
        /// <summary>
        /// [静态只读]内置图标C字。
        /// </summary>
        public static BitmapImage InnerIcon_C
        {
            get { return PictureBox.innerIcon_C; }
        }

        private static BitmapImage innerIcon_D;
        /// <summary>
        /// [静态只读]内置图标D字。
        /// </summary>
        public static BitmapImage InnerIcon_D
        {
            get { return PictureBox.innerIcon_D; }
        }

        private static BitmapImage innerIcon_X;
        /// <summary>
        /// [静态只读]内置图标X。可当叉号用。
        /// </summary>
        public static BitmapImage InnerIcon_X
        {
            get { return PictureBox.innerIcon_X; }
        }

        private static BitmapImage innerIcon_Right;
        /// <summary>
        /// [静态只读]内置图标，对勾号。
        /// </summary>
        public static BitmapImage InnerIcon_Right
        {
            get { return PictureBox.innerIcon_Right; }
        }

        private static BitmapImage innerIcon_Question;
        /// <summary>
        /// [静态只读]内置图标，问号。
        /// </summary>
        public static BitmapImage InnerIcon_Question
        {
            get { return PictureBox.innerIcon_Question; }
        }

        /// <summary>
        /// [只写]更新图像数据。图片框的图像数据，是用Base64文本存储到Xml文档中的。
        /// </summary>
        [Tools.LunarProperty("ImageBase64", Enums.PropertyDateType.String)]
        public string ImageBase64
        {
            set
            {
                if (this.xmlData == null)
                    throw new Exception("PictureBox的XmlData节点为null。");

                XmlNode imgBase64Node = this.xmlData.SelectSingleNode(XmlTags.ImageBase64Tag);
                if (imgBase64Node == null)
                {
                    this.xmlData.AppendXmlAsChild("<" + XmlTags.ImageBase64Tag + ">" + value + "</" + XmlTags.ImageBase64Tag + ">");
                }
                else
                {
                    imgBase64Node.InnerText = value;
                }

                Build();
            }
        }

        private bool isImageCollapsed = false;
        /// <summary>
        /// [读写]是否折叠图像。如果需要在非指定位置添加层级标题文本的话，
        /// 可以使用这个功能配合ＪＫＬ键快速编辑。
        /// </summary>
        [Tools.LunarProperty("IsImageCollapsed", PropertyDateType.Bool)]
        public bool IsImageCollapsed
        {
            get { return isImageCollapsed; }
            set
            {
                isImageCollapsed = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute(XmlTags.IsImageCollapsedTag, value.ToString());
                }
                this.RefreshIsImageCollapsed();
            }
        }

        /// <summary>
        /// [只读]这个图片框是否是内置图标。
        /// </summary>
        public bool IsInnerIcon
        {
            get
            {
                XmlAttribute attrInnerIconName = this.xmlData.GetAttribute(XmlTags.InnerIconNameTag);
                if (attrInnerIconName != null) return true;
                else return false;
            }
        }

        private Image mainImage = new Image() { ToolTip = "按Ctrl双击更换图片" };
        /// <summary>
        /// [只读]用于承载图像的Image。
        /// </summary>
        public Image MainImage
        {
            get { return mainImage; }
        }

        private Dock textDock = Dock.Right;
        /// <summary>
        /// [读写]文本位置。分：上、下、左、右四种。
        /// </summary>
        [Tools.LunarProperty("TextDock", Enums.PropertyDateType.Dock)]
        public Dock TextDock
        {
            get { return textDock; }
            set
            {
                textDock = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute(XmlTags.TextDockTag, value.ToString());
                }
                this.RefreshTextPanelLocatin();
            }
        }

        private double zoomValue = 0;
        [Tools.LunarProperty("ZoomValue", Enums.PropertyDateType.Double)]
        public double ZoomValue
        {
            get { return this.zoomValue; }
            set
            {
                this.zoomValue = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute(XmlTags.ZoomValueTag, value.ToString());
                    this.RfreshZoomValue();
                }
            }
        }

        #endregion


        #region 方法=========================================================================================================

        /// <summary>
        /// 从后台Xml文本中读取Base64文本并转换成图像数据。
        /// </summary>
        public override void Build()
        {
            base.Build();//这句真不能缺！！！

            if (this.xmlData == null)
            {
                mainImage.Width = PictureBox.defaultBitmap.PixelWidth;
                mainImage.Height = PictureBox.defaultBitmap.PixelHeight;
                mainImage.Source = PictureBox.defaultBitmap;
                return;
            }

            XmlAttribute attrInnerIconName = this.xmlData.GetAttribute(XmlTags.InnerIconNameTag);
            if (attrInnerIconName == null || attrInnerIconName.Value.Length <= 0)
            {
                try
                {
                    #region 读取图片数据。
                    XmlNode imgNode = this.XmlData.SelectSingleNode(XmlTags.ImageBase64Tag);

                    //图片可能无数据。
                    string imgDataText = null;

                    if (imgNode != null)
                    {
                        imgDataText = imgNode.InnerText;
                    }

                    BitmapImage bmp = new BitmapImage();

                    if (imgDataText != null && imgDataText.Length > 0)
                    {
                        byte[] b = Convert.FromBase64String(imgDataText);
                        bmp.BeginInit();
                        bmp.StreamSource = new MemoryStream(b);
                        bmp.EndInit();
                    }
                    else
                    {
                        bmp = PictureBox.defaultBitmap;
                    }

                    mainImage.Width = bmp.PixelWidth;
                    mainImage.Height = bmp.PixelHeight;
                    mainImage.Source = bmp;
                    #endregion
                }
                catch (Exception ex)
                {
                    MessageBox.Show("　　图片框构造时出现异常。异常信息如下：\r\n" + ex.Message + ex.StackTrace,
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            else
            {
                #region 读入内置图标。

                switch (attrInnerIconName.Value.ToLower())
                {
                    case "a":
                        {
                            mainImage.Source = innerIcon_A; break;
                        }
                    case "b":
                        {
                            mainImage.Source = innerIcon_B; break;
                        }
                    case "c":
                        {
                            mainImage.Source = innerIcon_C; break;
                        }
                    case "d":
                        {
                            mainImage.Source = innerIcon_D; break;
                        }
                    case "x":
                        {
                            mainImage.Source = innerIcon_X; break;
                        }
                    case "arrow":
                        {
                            mainImage.Source = innerIcon_Arrow; break;
                        }
                    case "question":
                        {
                            mainImage.Source = innerIcon_Question; break;
                        }
                    case "right":
                        {
                            mainImage.Source = innerIcon_Right; break;
                        }
                    default:
                        {
                            mainImage.Source = defaultBitmap; break;
                        }
                }
                #endregion
            }

            XmlAttribute attrDock = this.xmlData.GetAttribute(XmlTags.DockTag);
            if (attrDock != null)
            {
                this.textDock = (Dock)Enum.Parse(typeof(Dock), attrDock.Value);
            }

            XmlAttribute attrZoomValue = this.xmlData.GetAttribute(XmlTags.ZoomValueTag);
            if (attrZoomValue != null)
            {
                this.zoomValue = double.Parse(attrZoomValue.Value);
            }

            XmlAttribute attrTextDock = this.xmlData.GetAttribute(XmlTags.TextDockTag);
            if (attrTextDock != null)
            {
                this.textDock = (Dock)Enum.Parse(typeof(Dock), attrTextDock.Value);
            }

            this.RefreshLocation();

            this.RefreshWidgetBackColor();//刷新由此类调用。读取值都在上级。
            this.RefreshWidgetForeColor();
            this.RefreshWidgetLineColor();
            this.RefreshWidgetLineWidth();

            this.RfreshZoomValue();
            this.RefreshTextPanelLocatin();
        }
        
        public void RefreshIsImageCollapsed()
        {
            if (this.isImageCollapsed)
            {
                mainImage.Visibility = Visibility.Collapsed;
            }
            else
            {
                mainImage.Visibility = Visibility.Visible;
            }
        }

        public bool IsTextAraeVisible
        {
            get
            {
                XmlNode paragraphSetNode = this.ParagraphSetNode;

                if ((paragraphSetNode == null || paragraphSetNode.ChildNodes.Count <= 0) &&
                    string.IsNullOrEmpty(this.AutoNumberString))
                {
                    return false;
                }

                return true;
            }
        }

        public override void RefreshText()
        {
            base.RefreshText();

            RefreshIsTextVisible();

            XmlNodeList paragraphNodeList = this.ParagraphSetNode.SelectNodes(XmlTags.ParagraphTag);
            if (paragraphNodeList.Count <= 0 && string.IsNullOrEmpty(this.AutoNumberString))
            {
                this.mainTextPanel.Visibility = Visibility.Collapsed; return;
            }

            if (paragraphNodeList.Count == 1)
            {
                XmlNodeList textNodeList = paragraphNodeList[0].SelectNodes(XmlTags.TextTag);

                if (textNodeList.Count <= 0 && string.IsNullOrEmpty(this.AutoNumberString))
                {
                    this.mainTextPanel.Visibility = Visibility.Collapsed; return;
                }

                if (textNodeList.Count == 1)
                {
                    string text = textNodeList[0].InnerText;
                    if (text == null || text.Length <= 0 ||
                        text == "\r\n" || text == "\r" || text == "\n")
                    {
                        this.mainTextPanel.Visibility = Visibility.Collapsed; return;
                    }
                }
            }
        }

        public override void RefreshIsTextVisible()
        {
            //图片框和组有自己的逻辑
            //没有文本内容时“IsTextAreaVisible”优先，文本区域总是不显示，
            //不管继承的“isTextVisible”的值如何。

            if (this.IsTextAraeVisible)
            {
                if (IsTextVisible == false)//注意：不是“IsTextAreaVisible”
                {
                    this.mainTextPanel.Visibility = Visibility.Hidden;
                    this.textHideAdorner.Visibility = Visibility.Visible;
                }
                else
                {
                    this.mainTextPanel.Visibility = Visibility.Visible;
                    this.textHideAdorner.Visibility = Visibility.Collapsed;
                }
            }
            else
            {
                this.mainTextPanel.Visibility = Visibility.Collapsed;
                this.textHideAdorner.Visibility = Visibility.Collapsed;
            }
        }

        public override void RefreshTextPanelLocatin()
        {
            this.RefreshIsTextVisible();

            switch (this.textDock)
            {
                case Dock.Top:
                    {
                        DockPanel.SetDock(this.mainImage, Dock.Bottom);
                        this.mainImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                        this.mainTextPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                        DockPanel.SetDock(this.mainTextPanel, Dock.Top); break;
                    }
                case Dock.Left:
                    {
                        DockPanel.SetDock(this.mainImage, Dock.Right);
                        this.mainImage.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                        this.mainTextPanel.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                        DockPanel.SetDock(this.mainTextPanel, Dock.Left); break;
                    }
                case Dock.Right:
                    {
                        DockPanel.SetDock(this.mainImage, Dock.Left);
                        this.mainImage.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                        this.mainTextPanel.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                        DockPanel.SetDock(this.mainTextPanel, Dock.Right); break;
                    }
                default://Bottom
                    {
                        DockPanel.SetDock(this.mainImage, Dock.Top);
                        this.mainImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                        this.mainTextPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                        DockPanel.SetDock(this.mainTextPanel, Dock.Bottom); break;
                    }
            }
        }

        private void RfreshZoomValue()
        {
            if (this.zoomValue == 0)
            {
                this.mainImage.LayoutTransform = null;
            }
            else this.mainImage.LayoutTransform = new ScaleTransform(zoomValue, zoomValue);
        }
        #endregion


    }
}
